package com.madzone.wiki.gae.ds;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.jdo.PersistenceManager;

import com.ecyrd.jspwiki.NoRequiredPropertyException;
import com.ecyrd.jspwiki.QueryItem;
import com.ecyrd.jspwiki.WikiEngine;
import com.ecyrd.jspwiki.WikiPage;
import com.ecyrd.jspwiki.providers.ProviderException;
import com.ecyrd.jspwiki.providers.WikiPageProvider;
import com.madzone.wiki.gae.ds.model.PMF;

public class GoogleDataStoreWikiPageProvider implements WikiPageProvider
{
	private WikiEngine mWikiEngine;
	private Properties mProperties;

    public void deletePage( String pageName ) throws ProviderException
    {
        // TODO Auto-generated method stub
        
    }

    public void deleteVersion( String pageName, int version ) throws ProviderException
    {
        // TODO Auto-generated method stub
        
    }

    public Collection findPages( QueryItem[] query )
    {
        // TODO Auto-generated method stub
        return new ArrayList<WikiPage>();
    }

    public Collection getAllChangedSince( Date date )
    {
        try {
			return getAllPages();
		} catch (ProviderException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return new ArrayList<WikiPage>();
    }

    public Collection getAllPages() throws ProviderException
    {
    	List<com.madzone.wiki.gae.ds.model.WikiPage> gaeWikiPages = com.madzone.wiki.gae.ds.model.WikiPage.getAllWikiPages();
    	List<WikiPage> pages = new ArrayList<WikiPage>();
    	for (com.madzone.wiki.gae.ds.model.WikiPage gaeWikiPage:gaeWikiPages) {
    		pages.add(getJSPWikiPage(mWikiEngine, gaeWikiPage));
    	}
    	return pages;
    }

    public int getPageCount() throws ProviderException
    {
    	return com.madzone.wiki.gae.ds.model.WikiPage.getWikiPagesCount();
    }

    public WikiPage getPageInfo( String page, int version ) throws ProviderException
    {
    	if (pageExists(page)) {
	    	com.madzone.wiki.gae.ds.model.WikiPage gaeWikiPage = com.madzone.wiki.gae.ds.model.WikiPage.getByName(page, version, false);
			WikiPage wikiPage = GoogleDataStoreWikiPageProvider.getJSPWikiPage(mWikiEngine, gaeWikiPage);
			return wikiPage;
    	}
    	return null;
    }

    public String getPageText( String page, int version ) throws ProviderException
    {
        if (pageExists(page)) {
        	com.madzone.wiki.gae.ds.model.WikiPage gaeWikiPage = com.madzone.wiki.gae.ds.model.WikiPage.getByName(page, version, true);
        	return gaeWikiPage.getWikiTextString();
        }
        return null;
    }

    public List getVersionHistory( String page ) throws ProviderException
    {
    	List<WikiPage> history = new ArrayList<WikiPage>();
    	PersistenceManager pm = null;
    	if (pageExists(page)) {
    		pm = PMF.getPM();
    		List<com.madzone.wiki.gae.ds.model.WikiPage> gaeWikiPageVersions = com.madzone.wiki.gae.ds.model.WikiPage.getByName(page, false);
    		for (com.madzone.wiki.gae.ds.model.WikiPage gaeWikiPage : gaeWikiPageVersions) {
	    		WikiPage wikiPage = GoogleDataStoreWikiPageProvider.getJSPWikiPage(mWikiEngine, gaeWikiPage);
	    		history.add(wikiPage);
    		}
    	}
    	try {
    		//pm.close();
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    	return history;
    }

    public void movePage( String from, String to ) throws ProviderException
    {
    	PersistenceManager pm = PMF.getPM();
    	List<com.madzone.wiki.gae.ds.model.WikiPage> wikiPages = com.madzone.wiki.gae.ds.model.WikiPage.getByName(from);
    	for (com.madzone.wiki.gae.ds.model.WikiPage wikiPage : wikiPages) {
    		wikiPage.setName(to);
    	}
    	//pm.close();
    }

    public boolean pageExists( String page )
    {
    	com.madzone.wiki.gae.ds.model.WikiPage gaeWikiPage = com.madzone.wiki.gae.ds.model.WikiPage.getByName(page, -1, false);
    	return gaeWikiPage != null;
    }

    public void putPageText( WikiPage page, String text ) throws ProviderException
    {
        long wikiTextSize = text.getBytes().length;
        Date now = new Date();
        com.madzone.wiki.gae.ds.model.WikiPage gaeWikiPage = null;
        if (!pageExists(page.getName())) {
	        gaeWikiPage = new com.madzone.wiki.gae.ds.model.WikiPage();
	        gaeWikiPage.setVersion(1);
	        
        } else {
        	gaeWikiPage = new com.madzone.wiki.gae.ds.model.WikiPage();
        	gaeWikiPage.setVersion(page.getVersion() + 1);
        }
        gaeWikiPage.setAttributes(page.getAttributes());
    	gaeWikiPage.setAuthor(page.getAuthor());
    	gaeWikiPage.setFileSize(wikiTextSize);
    	gaeWikiPage.setLastModifiedDate(now);
    	gaeWikiPage.setName(page.getName());
    	gaeWikiPage.setWikiName(page.getWiki());
    	gaeWikiPage.setWikiText(text);
        gaeWikiPage.save();
    }

    public String getProviderInfo()
    {
        return "JSPWiki for Google App Engine";
    }

    public void initialize( WikiEngine engine, Properties properties ) throws NoRequiredPropertyException, IOException
    {
    	mWikiEngine = engine;
    	mProperties = properties;
    }
    
    private static WikiPage getJSPWikiPage(WikiEngine engine, com.madzone.wiki.gae.ds.model.WikiPage gaeWikiPage) {
    	WikiPage jspWikiPage = new WikiPage(engine, gaeWikiPage.getName());
    	jspWikiPage.setAuthor(gaeWikiPage.getAuthor());
    	jspWikiPage.setLastModified(gaeWikiPage.getLastModifiedDate());
    	jspWikiPage.setSize(gaeWikiPage.getFileSize());
    	jspWikiPage.setVersion(gaeWikiPage.getVersion());
    	Map<String, String> attributes = gaeWikiPage.getAttributes();
    	if (attributes != null) {
    		for(Map.Entry<String, String> entry : attributes.entrySet()) {
    			jspWikiPage.setAttribute(entry.getKey(), entry.getValue());
    		}
    	}
    	return jspWikiPage;
    }

}
